package com.sale.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sale.common.core.domain.R;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.core.utils.StringUtils;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.system.api.RemoteUnitService;
import com.sale.system.api.domain.dto.FinishAndRawDto;
import com.sale.system.api.domain.dto.MaterialAuxiliaryDto;
import com.sale.system.api.model.MaterialUnitDto;
import com.sale.system.domain.*;
import com.sale.system.domain.dto.MaterialFinishedDto;
import com.sale.system.domain.dto.ProjectRecursionDto;
import com.sale.system.domain.dto.SysCategoryDto;
import com.sale.system.domain.dto.SysTheDropDto;
import com.sale.system.domain.vo.MaterialAlarmVo;
import com.sale.system.domain.vo.MaterialFinishedVo;
import com.sale.system.domain.vo.MaterialMqMessageVo;
import com.sale.system.mapper.*;
import com.sale.system.service.*;
import com.sale.system.util.MaterialMqUtil;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 成品信息实现类
 * @Param
 * @Date 22-11-28
 * @Author hl
 **/
@RequiredArgsConstructor
@Service
public class MaterialFinishedServiceImpl implements IMaterialFinishedService {

    private final MaterialFinishedMapper materialFinishedMapper;

    private final ISysMidSplitService sysMidSplitService;

    private final ISysDocumentService sysDocumentService;

    private final SysAuxiliaryUnitMapper sysAuxiliaryUnitMapper;

    private final MaterialAuxiliaryMapper materialAuxiliaryMapper;

    private final MaterialRawMapper materialRawMapper;

    private final SysAuxiliaryUnitDetailMapper sysAuxiliaryUnitDetailMapper;

    private final SysTheAlarmMapper sysTheAlarmMapper;
    @Lazy
    @Resource
    private MaterialRawServiceImpl materialRawServiceImpl;

    private final ISysCategoryService sysCategoryService;

    /**
     * 新增成品信息
     *
     * @param materialFinished 成品信息
     * @return 成品集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertFinished(MaterialFinishedVo materialFinished) throws Exception {
        MaterialFinished finished = new MaterialFinished();
        BeanUtils.copyProperties(materialFinished, finished);
        finished.setMaterialId(IdWorker.getId());
        List<SysAuxiliaryUnitDetail> list2 = materialFinished.getList();
        StringBuffer moreUnit = new StringBuffer();
        for (SysAuxiliaryUnitDetail item : list2) {
            moreUnit.append(item.getAuxiliaryId()).append(",");
            item.setMaterialId(finished.getMaterialId());
        }
        finished.setMaterialMoreUnit(moreUnit.toString().substring(0, moreUnit.length() - 1));
        //成品编码按照类别配置中得生成
        SysCategoryDto sysCategoryDto = sysCategoryService.selectCategoryById(materialFinished.getMaterialType());
        String s = sysMidSplitService.selectSplitStr(sysCategoryDto.getCodeRule());
        if (StringUtils.isEmpty(s)) {
            throw new GlobalException("编码生成失败，请检查配置");
        }
        finished.setMaterialCode(s);
        finished.setCreateBy(LoginHelper.getUsername());
        int os = materialFinishedMapper.insert(finished);
        if (os > 0) {
            if (materialFinished.getAlarmCode() != null) {
                List<SysTheAlarm> list = materialRawServiceImpl.alarmConfiguration(materialFinished.getAlarmCode());
                long op = finished.getMaterialId();
                String materialCode = finished.getMaterialCode();
                for (SysTheAlarm sysTheAlarm : list) {
                    String roles = "";
                    for (int i = 0; i < sysTheAlarm.getRoleIds().size(); i++) {
                        roles = roles + sysTheAlarm.getRoleIds().get(i);
                        if (sysTheAlarm.getRoleIds().size() - 1 != i) {
                            roles = roles + ",";
                        }
                    }
                    sysTheAlarm.setAlarmRoleId(roles);
                    sysTheAlarm.setAlarmAssociatedId(op);
                    sysTheAlarm.setAlarmOfMaterial(4);
                    sysTheAlarm.setAlarmMaterialCode(materialCode);
                }
                if (list.size() != 0) {
                    os = sysTheAlarmMapper.insertSysTheAlarm(list);
                }
            }
            if (os == 0) {
                throw new SQLException("抛出异常");
            }
        }
        //mq发送消息
        String userIdStr = LoginHelper.getUserIdStr();
        MaterialMqMessageVo materialMqVo = new MaterialMqMessageVo();
        BeanUtils.copyProperties(finished, materialMqVo);
        materialMqVo.setUserIdStr(userIdStr);
        materialMqVo.setMaterialType(finished.getMaterialType());
        materialMqVo.setMaxInventory(String.valueOf(finished.getMaxInventory()));
        MaterialMqUtil.materialMqSend(materialMqVo);

        List<MaterialAuxiliary> list = materialFinished.getAuxiliaryAttribute();
        if (list != null) {
            for (MaterialAuxiliary auxiliary :
                list) {
                auxiliary.setMaterialId(finished.getMaterialId());
                auxiliary.setAuxiliaryId(IdWorker.getId());
            }
            materialAuxiliaryMapper.insertBatch(list);
        }
        if (list2.get(0).getAuxiliaryId() != null) {
            sysAuxiliaryUnitDetailMapper.insertBatch(list2);
        }
        return os;
    }

    /**
     * 删除成品信息
     *
     * @param materialId 成品id
     * @return 成品集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteFinishedById(String materialId) throws Exception {
        String[] materialIdS = materialId.split(",");
        ArrayList<String> arrayList = new ArrayList<>();
        for (String str :
            materialIdS) {
            arrayList.add(str);
            //删除对应属性
            HashMap<String, Object> map = new HashMap<>();
            map.put("material_id", str);
            materialAuxiliaryMapper.deleteByMap(map);
            sysAuxiliaryUnitDetailMapper.deleteByMap(map);
        }
        //mq发送消息(删除)
        MaterialMqMessageVo materialMqVo = new MaterialMqMessageVo();
        materialMqVo.setIdStr(materialId);
        MaterialMqUtil.materialMqSendDelete(materialMqVo);

        return materialFinishedMapper.deleteBatchIds(arrayList);
    }


    /**
     * 查询单个成品信息
     *
     * @param materialId 成品信息ID
     * @return 成品信息集合
     */
    @Override
    public MaterialFinishedDto selectFinishedById(long materialId) {
        MaterialFinished finished = materialFinishedMapper.selectById(materialId);
        MaterialFinishedDto dto = new MaterialFinishedDto();
        BeanUtils.copyProperties(finished, dto);
        List<MaterialAuxiliaryDto> list = materialAuxiliaryMapper.selectAuxiliaryById(materialId);
        Map<String, Object> map = new HashMap<>();
        map.put("material_id", materialId);
        List<SysAuxiliaryUnitDetail> list1 = sysAuxiliaryUnitDetailMapper.selectByMap(map);
        //获取告警数据
        int alarmOfMaterial = 4;
        List<SysTheAlarm> theList = sysTheAlarmMapper.selectSysTheAlarmList(materialId, alarmOfMaterial);
        MaterialAlarmVo materialAlarmVo = materialRawServiceImpl.alarmConfigtType(theList);
        dto.setAlarmCode(materialAlarmVo);
        dto.setAuxiliaryAttribute(list);
        dto.setList(list1);
        return dto;
    }

    /**
     * 修改成品信息
     *
     * @param
     * @return 成品信息集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMaterialFinishedEdit(MaterialFinishedVo materialFinished) throws Exception {
        MaterialFinished materialFinished1 = new MaterialFinished();
        List<SysAuxiliaryUnitDetail> list2 = materialFinished.getList();
        StringBuffer moreUnit = new StringBuffer();
        for (SysAuxiliaryUnitDetail item : list2) {
            moreUnit.append(item.getAuxiliaryId()).append(",");
            item.setMaterialId(materialFinished.getMaterialId());
        }
        BeanUtils.copyProperties(materialFinished, materialFinished1);
    /*    materialFinished1.setMaterialName(materialFinished.getMaterialName())
            .setMaterialType(materialFinished.getMaterialType())
            .setMaterialSpec(materialFinished.getMaterialSpec())
            .setPurchasePrice(materialFinished.getPurchasePrice())
            .setForewarning(materialFinished.getForewarning())
            .setMinInventory(materialFinished.getMinInventory())
            .setMaxInventory(materialFinished.getMaxInventory())
            .setMaterialMoreUnit(moreUnit.toString().substring(0,moreUnit.length()-1))
            .setRemark(materialFinished.getRemark());*/
        int ors = materialFinishedMapper.updateById(materialFinished1);
        if (ors > 0) {
            long materialId = materialFinished.getMaterialId();
            sysTheAlarmMapper.deleteSysTheAlarmOnById(materialId);
            if (ors > 0) {
                long sy = materialFinished.getMaterialId();
                String materialCode = materialFinished.getMaterialCode();
                List<SysTheAlarm> list = materialRawServiceImpl.alarmConfiguration(materialFinished.getAlarmCode());
                for (SysTheAlarm sysTheAlarm : list) {
                    String roles = "";
                    for (int i = 0; i < sysTheAlarm.getRoleIds().size(); i++) {
                        roles = roles + sysTheAlarm.getRoleIds().get(i);
                        if (sysTheAlarm.getRoleIds().size() - 1 != i) {
                            roles = roles + ",";
                        }
                    }
                    sysTheAlarm.setAlarmRoleId(roles);
                    sysTheAlarm.setAlarmAssociatedId(sy);
                    sysTheAlarm.setAlarmOfMaterial(4);
                    sysTheAlarm.setAlarmMaterialCode(materialCode);
                }
                if (list.size() != 0) {
                    ors = sysTheAlarmMapper.insertSysTheAlarm(list);
                }
                if (ors == 0) {
                    throw new SQLException("抛出异常");
                }
            } else {
                throw new SQLException("抛出异常");
            }
        }
        //mq发送消息
        String userIdStr = LoginHelper.getUserIdStr();
        MaterialMqMessageVo materialMqVo = new MaterialMqMessageVo();
        BeanUtils.copyProperties(materialFinished1, materialMqVo);
        materialMqVo.setUserIdStr(userIdStr);
        materialMqVo.setMaterialMoreUnit(materialFinished1.getMaterialMoreUnit());
        materialMqVo.setMaterialUnit(materialFinished1.getMaterialUnit());
        materialMqVo.setMaterialType(materialFinished1.getMaterialType());
        materialMqVo.setMaterialId(materialFinished1.getMaterialId());
        materialMqVo.setMaxInventory(String.valueOf(materialFinished1.getMaxInventory()));
        MaterialMqUtil.materialMqSend(materialMqVo);

        List<MaterialAuxiliary> list = materialFinished.getAuxiliaryAttribute();
        if (list != null) {
            //删除对应属性
            HashMap<String, Object> map = new HashMap<>();
            long materialId = materialFinished1.getMaterialId();
            map.put("material_id", materialId);
            materialAuxiliaryMapper.deleteByMap(map);
            sysAuxiliaryUnitDetailMapper.deleteByMap(map);
            //重新新增对应属性
            for (MaterialAuxiliary auxiliary :
                list) {
                auxiliary.setMaterialId(materialId);
            }
            //批量新增物料属性信息
            materialAuxiliaryMapper.insertBatch(list);
        }
        sysAuxiliaryUnitDetailMapper.insertBatch(list2);
        return ors;
    }

    /**
     * 树结构展示
     *
     * @param
     * @return 成品信息集合
     */
    @Override
    public List<ProjectRecursionDto> selectChildrenFinishedThe() {
        return buildMenuTree(materialFinishedMapper.selectChildrenFinishedThe());
    }

    /**
     * 树结构递归
     *
     * @param
     * @return
     */
    public static List<ProjectRecursionDto> buildMenuTree(List<ProjectRecursionDto> menus) {
        List<ProjectRecursionDto> returnList = new ArrayList<ProjectRecursionDto>();
        List<String> tempList = new ArrayList<String>();
        for (ProjectRecursionDto dept : menus) {
            tempList.add(dept.getId());
        }
        for (Iterator<ProjectRecursionDto> iterator = menus.iterator(); iterator.hasNext(); ) {
            ProjectRecursionDto menu = (ProjectRecursionDto) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(menu.getParentId())) {
                recursionFn(menus, menu);
                if (menu.getParentId() == 0) {
                    returnList.add(menu);
                }
            }
        }
        if (returnList.isEmpty()) {
            returnList = menus;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private static void recursionFn(List<ProjectRecursionDto> list, ProjectRecursionDto t) {
        // 得到子节点列表
        List<ProjectRecursionDto> childList = getChildList(list, t);
        t.setChildren(childList);
        for (ProjectRecursionDto tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 递归列表
     */
    private static List<ProjectRecursionDto> getChildList(List<ProjectRecursionDto> list, ProjectRecursionDto t) {
        List<ProjectRecursionDto> tlist = new ArrayList<ProjectRecursionDto>();
        Iterator<ProjectRecursionDto> it = list.iterator();
        while (it.hasNext()) {
            ProjectRecursionDto n = (ProjectRecursionDto) it.next();
            if (String.valueOf(n.getParentId().longValue()).equals(t.getId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private static boolean hasChild(List<ProjectRecursionDto> list, ProjectRecursionDto t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 根据物料编码查询详情（成品信息）
     *
     * @param materialCode
     * @return
     */
    @Override
    public MaterialFinished selectMaterialFinishedMaterialCode(String materialCode) {
        return materialFinishedMapper.selectMaterialFinishedMaterialCode(materialCode);
    }

    /**
     * 分页查询成品信息
     *
     * @param materialFinished 成品信息,pageQuery 分页参数
     * @return TableDataInfo<MaterialFinishedDto>
     */
    @Override
    public TableDataInfo<MaterialFinishedDto> selectFinishedList(MaterialFinishedVo materialFinished, PageQuery pageQuery) {
        Page<MaterialFinishedDto> page = materialFinishedMapper.selectFinishedList(pageQuery.build(), this.buildQueryWrapper(materialFinished));
        //渲染辅助属性
//        // 多单位
//        List<SysTheDropDto> listThe = sysAuxiliaryUnitMapper.selectMultiMeteringUnitAllList();
//        Map<String, String> map = listThe.stream()
//            .collect(Collectors.toMap(SysTheDropDto::getValue, SysTheDropDto::getLabel));

        //单位集合
        //   Map<String, MaterialUnitDto> unitByCodeToMap = remoteUnitService.getUnitByCodeToMap();
        List<MaterialFinishedDto> list = page.getRecords();
        for (MaterialFinishedDto dto :
            list) {
            // String unit = dto.getMaterialUnit();
       /*     if (unit != null) {
                dto.setMaterialUnitDict(unitByCodeToMap.get(unit).getUnitName());
            }*/
            dto.setAuxiliaryAttribute(materialAuxiliaryMapper.selectAuxiliaryById(dto.getMaterialId()));
            //类别
            // dto.setMaterialCategory("2");
            // dto.setMaterialCategoryDict("成品");
        }
        return TableDataInfo.build(page);
    }

    private Wrapper<MaterialFinishedVo> buildQueryWrapper(MaterialFinishedVo materialFinished) {
        Map<String, Object> params = materialFinished.getParams();
        QueryWrapper<MaterialFinishedVo> wrapper = Wrappers.query();
        wrapper
            .like(ObjectUtil.isNotNull(materialFinished.getMaterialCode()), "t1.material_code", materialFinished.getMaterialCode())
            .like(StringUtils.isNotBlank(materialFinished.getMaterialName()), "t1.material_name", materialFinished.getMaterialName())
            .eq(StringUtils.isNotBlank(materialFinished.getMaterialStatus()), "t1.material_status", materialFinished.getMaterialStatus())
            .eq(StringUtils.isNotNull(materialFinished.getMaterialType()), "t1.material_type", materialFinished.getMaterialType()).between(params.get("beginTime") != null && params.get("endTime") != null,
                "t1.create_time", params.get("beginTime"), params.get("endTime"));
        return wrapper;
    }

    /**
     * 根据物料编码查询成品信息
     *
     * @param materialCode
     * @return
     */
    @Override
    public MaterialFinishedDto getByFinishedMaterialCode(String materialCode) {
        return materialFinishedMapper.getByFinishedMaterialCode(materialCode);
    }

    /**
     * 根据编码获取物料信息（财务成品调整模块使用）
     */
    @Override
    public FinishAndRawDto getFinishAndRaw(String materialCode) {
        FinishAndRawDto result;
        //查询成品信息
        FinishAndRawDto finish = materialFinishedMapper.getFinishAndRaw(materialCode);
        //查询原料信息
        FinishAndRawDto raw = materialRawMapper.getFinishAndRaw(materialCode);
        if (finish != null) {
            result = finish;
        } else {
            result = raw;
        }
        return result;
    }

    /**
     * 成品冻结
     */
    @Override
    public int updateEditFreeze(Long materialId) {
        MaterialFinished finished = new MaterialFinished();
        finished.setMaterialStatus(1);
        finished.setMaterialId(materialId);
        return materialFinishedMapper.updateById(finished);
    }

    /**
     * 成品解冻
     */
    @Override
    public int updateEditThaw(Long materialId) {
        MaterialFinished finished = new MaterialFinished();
        finished.setMaterialStatus(2);
        finished.setMaterialId(materialId);
        return materialFinishedMapper.updateById(finished);
    }


}
